﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WindowsLive;
using FeedReader.Shared.Data;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace MvcFrontEnd.Models
{
    public class TheUser : IDisposable
    {
        public string Name { get; set; }
        public string ID { get; set; }
        public string Type { get; set; }
        // Track whether Dispose has been called.
        private bool disposed = false;
        public static TheUser GetUser(HttpRequest therequest)
        {
            return LoadCookieData(therequest);
        }
        public static TheUser GetUser(HttpRequestBase therequest)
        {
            return LoadCookieData(therequest);
        }
        private static UsersDataModel TryGetUser(string id)
        {
            CloudStorageAccount acc = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
            UsersDataSource source = new UsersDataSource(acc);
            var result = source.Select(id);
            if (result.Count() > 0)
            {
                return result.ElementAt(0);
            }
            return null;
        }
        private static string GetId(string token)
        {
            return new WindowsLiveLogin(RoleEnvironment.GetConfigurationSettingValue("wll_appid"), RoleEnvironment.GetConfigurationSettingValue("wll_secret")).ProcessToken(token).Id;
        }
        static TheUser LoadCookieData(HttpRequestBase therequest)
        {
            var cookie = therequest.Cookies["webauthtoken"];
            TheUser result = new Models.TheUser();

            string id = null;
            if (cookie != null)
            {
                id = GetId(cookie.Value);
                var user = TryGetUser(id);
                try
                {
                    result.ID = user.UserID;
                    result.Name = user.UserFName;
                    result.Type = user.Type;
                }
                catch
                {
                    result.Name = id;
                    result.ID = id;
                }
            }
            else
            {
                result.ID = "0000";
                result.Name = "Guest";
                result.Type = "Standard";
            }
            return result;
        }
        static TheUser LoadCookieData(HttpRequest therequest)
        {
            var cookie = therequest.Cookies["webauthtoken"];
            TheUser result = new Models.TheUser();

            string id = null;
            if (cookie != null)
            {
                id = GetId(cookie.Value);
                var user = TryGetUser(id);
                try
                {
                    result.ID = user.UserID;
                    result.Name = user.UserFName;
                    result.Type = user.Type;
                }
                catch
                {
                    result.Name = id;
                }
            }
            else
            {
                result.ID = "0000";
                result.Name = "Guest";
                result.Type = "Standard";
            }
            return result;
        }

        #region IDisposable Members

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        void IDisposable.Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                }

                // Note disposing has been done.
                disposed = true;

            }
        }

        #endregion
    }

}